﻿using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
using Mrsoft.Common;
using Mrsoft.Model;

namespace Mrsoft.Core
{
    /// <summary>
    /// 游戏数据解析执行类
    /// </summary>
    static class LoadData
    {

        public static string fileName = "./system/data.obj";

        public static void FirstLoadData() {

            if (File.Exists(fileName)) {
                try {
                    var str = File.ReadAllText(fileName);
                    DirectDealGame.Data = Newtonsoft.Json.JsonConvert.DeserializeObject<GameData>(str);
                }
                catch (Exception ex) {
                    MsgListener.CommonMsgShow("数据解析", ex.Message);
                    File.Delete(fileName);
                }
            }
            //如果没有解析出来就直接创建
            if (DirectDealGame.Data == null) {
                DirectDealGame.Data = new GameData();
            }
            DirectDealGame.Data.IsReady = false;
            if (!string.IsNullOrEmpty(DirectDealGame.Data.GamePath)) {
                var dVer = new Config<int>(@".\ver.conf", "data", 23);
                var gVer = NativeMethods.IniReadValue(DirectDealGame.Data.GamePath, "Version", "Latest");
                if (gVer == DirectDealGame.Data.GameVersion && dVer.Value == DirectDealGame.Data.LocalVersion) {
                    DirectDealGame.Data.IsReady = true;
                    MsgListener.CommonMsgShow("数据解析", "数据无变化直接解析完成");
                }
            }
        }

        public static void LoadFromGame(Process game) {
            try {
                //获取游戏的版本号
                var sb = new StringBuilder(game.MainModule.FileName.ToLower());
                sb.Replace(@"bin\game.exe", "");
                sb.Append(@"Patch\patchinfo.txt");
                MsgListener.CommonMsgShow("数据解析", sb.ToString());

                #region 加载原始数据文件更新数据
                //解密原始数据
                var datafile = @".\system\default.7z";
                if (!File.Exists(datafile)) {
                    MsgListener.CommonMsgShow("数据解析", "数据文件不存在");
                    return;
                }
                var fs = File.OpenRead(datafile);
                var extractor = new SevenZip.SevenZipExtractor(fs, "sunyu87");
                var ms = new MemoryStream();
                extractor.ExtractFile(0, ms);
                string xmlStr = Encoding.UTF8.GetString(ms.ToArray()).Replace("\n", "");
                ms.Dispose();
                fs.Dispose();
                extractor.Dispose();
                //内存数据读取
                var xDoc = new XmlDocument();
                xDoc.LoadXml(xmlStr);
                var buffer = new byte[0x500000];//007EFFFF      00            db 00 41AFFF
                IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.ProcessVmRead, false, game.Id);
                IntPtr iRead;


                var EntryPoint = 0x401000;

                var br = NativeMethods.ReadProcessMemory(hProcess, (IntPtr)EntryPoint, buffer, (IntPtr)buffer.Length, out iRead);
                NativeMethods.CloseHandle(hProcess);
                //使用原始文件和内存数据解析游戏
                if (!br)
                    throw new Exception("游戏数据读取失败,重新进行解析过程");
                var datMgr = new GameDataManager();
                datMgr.Analys(xDoc, EntryPoint, buffer);
                #endregion

                #region 将数据加载出来并且保存下来
                //数据保存和读出
                DirectDealGame.Data.GamePath = sb.ToString();
                DirectDealGame.Data.LocalVersion = new Config<int>(@".\ver.conf", "data", 23).Value;
                DirectDealGame.Data.GameVersion = NativeMethods.IniReadValue(DirectDealGame.Data.GamePath, "Version", "Latest");
                if (datMgr.GetData(DirectDealGame.Data, fileName)) {
                    DirectDealGame.Data.IsReady = true;
                    MsgListener.CommonMsgShow("数据解析", "由游戏解析数据成功");
                }
                #endregion

                new Config<int>("Serializable", "floorBagId", -1).Value = -1;
            }
            catch (Exception ex) {
                MsgListener.CommonMsgShow("数据解析", ex.Message);
            }
        }
    }
}
